package com.sumainfor.pc.gmio.service.impl.market;

import com.sumainfor.common.Constants;
import com.sumainfor.common.util.ContextUtils;
import com.sumainfor.common.util.DateUtils;
import com.sumainfor.common.util.JsonResult;
import com.sumainfor.common.utlis.ComUtils;
import com.sumainfor.common.utlis.CompuUtils;
import com.sumainfor.common.utlis.ConvertDateTime;
import com.sumainfor.common.utlis.ParamsCommon;
import com.sumainfor.pc.gmio.dao.MktFeign.BillOwnerMapper;
import com.sumainfor.pc.gmio.dao.UtilsMapper;
import org.apache.commons.collections.MapUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 功能描述:
 *
 * @Auther: zhlu
 * @Date: 2019/3/25 10:40
 * @Description:
 */
@Service
public class BillOwnerService {
    Logger log = LoggerFactory.getLogger(BillOwnerService.class);
    private ReentrantLock lock = new ReentrantLock(false);

    @Autowired
    BillOwnerMapper BillOwnerMapper;


    @Autowired
    UtilsMapper utilsMapper;

    String BiOutId = null;

    String TemId = null;

    @Autowired
    private ComUtils comUtils;
    /**
     * 功能描述:
     * 根据业主合同资料生成唐巢支付业主的账单
     * 1.新业主收房信息补全之前生成。
     * 2.续签业主在第一份合同到期之后定时任务生成
     *
     * @Author zhlu
     * @Description //TODO
     * @Date 2019/3/25 10:42
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean AddBillOwner(Map<String, Object> params) throws Exception {
        boolean result = false;
        /**
         * 加锁操作
         */
        lock.lock();
        try {
            try {
                //所有新增处理
                Map<String, Object> commonInsertParms = new HashMap<String, Object>();
                commonInsertParms.put("by", ContextUtils.getUserId());//操作人
                commonInsertParms.put("term", "2");// 创建端 Insert端： 1 租客端 2市场部 3 工程部   4运营部   5财务部  6总经办 7发展部
                commonInsertParms.put("fnc",
                        this.getClass().getSimpleName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName());// 创建Function名
                ParamsCommon.commonInsertParms(commonInsertParms);

                //合同开始时间
                DateTime StartTime = ConvertDateTime.dateFormatStrToTime(ConvertDateTime.FORMAT_FULL_DATETIME_EN, params.get("StartTime").toString());
                //合同结束时间
                DateTime EndTime = ConvertDateTime.dateFormatStrToTime(ConvertDateTime.FORMAT_FULL_DATETIME_EN, params.get("EndTime").toString());
                //租金支付方式。几个月一付
                int Charge = Integer.valueOf(params.get("Charge").toString());
                //付业主押金几个月
                int Pair = Integer.valueOf(params.get("Pair").toString());
                //付业主免租期
                int RentHoliday = Integer.valueOf(params.get("RentHoliday").toString());
                //合同周期的间隔月份，不考虑免租期
                int gapMonth = DateUtils.getMonthDiff(params.get("EndTime").toString(), params.get("StartTime").toString(), "yyyy-MM-dd") + 1;

                //收房月租
                double MonthPrice = Double.valueOf(params.get("MonthPrice").toString());
                //循环次数 合同周期除以付款周期，计算需要缴几次房租，如果有余就加一
                int forCount = gapMonth % Charge == 0 ? (gapMonth / Charge) : (gapMonth / Charge) + 1;

                //租金递增周期（年）
                int AscendingYea = Integer.valueOf(params.get("AscendingYea").toString());
                //租金递增类型   1.百分比   2.元
                int AscendingType = Integer.valueOf(params.get("AscendingType").toString());
//                //租金递增值
//                int AscendingVal = Integer.valueOf(params.get("AscendingVal").toString());
                //租金递增值
                double AscendingVal = Double.valueOf(params.get("AscendingVal").toString());


                log.info("免租期之前要交多少月房租" + ConvertDateTime.subDate(StartTime, EndTime, 2));
                log.info("免租期" + RentHoliday);
                log.info("每次缴房租，缴几个月Charge:" + Charge);
                log.info("合同周期内需要缴几次房租forCount:" + forCount);
                log.info("需要押几个月Pair:" + Pair);
                log.info("房屋月租金MonthPrice:" + MonthPrice);
                log.info("免租期之后要交多少个月gapMonth:" + gapMonth);
                if (Pair > 0) {//如果业主押金月份大于0，就说明有押金。就要生成账单-临时账单
                    //获取账单编号
                    Map<String, Object> temId = utilsMapper.getUUID(new HashMap<String, Object>() {{
                        put("uuid", "TemId");
                        put("database", Constants.DATA_SOURCE_GMIO);
                        put("surface", "tcgmio_bill_outlay_temporary");
                    }});
                    if (temId != null && (!temId.get("uuid").toString().equals(""))) {
                        int number = Integer.valueOf(temId.get("uuid").toString());
                        TemId = ComUtils.getLocalTrmSeqNum("lszd", number);
                    } else {
                        TemId = ComUtils.getLocalTrmSeqNum("lszd", 0);
                    }
                    //账单支出-临时账单
                    Map<String, Object> BillOutTemp = new HashMap<String, Object>();
                    BillOutTemp.put("TemId", TemId);//临时账单编号
                    BillOutTemp.put("CorId", params.get("CorId"));//当前账单归属公司，涉及到支付。不同公司走不同账户
                    BillOutTemp.put("TemType", 1);//临时账单类型   1.业主押金
                    BillOutTemp.put("SourceId", BiOutId);//账单支出主编号
                    BillOutTemp.put("HouId", params.get("HouId"));//房源编号
                    //                    BillOutTemp.put("HouInfoId",params.get("HouInfoId"));//房源详表编号\n项目首字母+项目四位路号三位楼号四位室号ABCD房间 如果整租就是Z
                    BillOutTemp.put("StemType", 1);//支出类型   1.业主  2.供应商  3.租客
                    BillOutTemp.put("StemId", params.get("OwId"));//业主编号
                    BillOutTemp.put("Cost", CompuUtils.mul(MonthPrice, Pair));//应支费用=业主合同月租金*押金月份
                    BillOutTemp.put("Remark", "付业主押金:" + CompuUtils.mul(MonthPrice, Pair));//临时账单备注
                    BillOutTemp.putAll(commonInsertParms);
                    BillOwnerMapper.AddBillTemOwner(BillOutTemp);
                }
                Double price = MonthPrice;
                for (int i = 1; i <= forCount; i++) {
                    log.info("FirstPayment====>" + params.get("FirstPayment").toString());
                    Map<String, Object> BillOut = new HashMap<String, Object>();
                    DateTime payStartTime = ConvertDateTime.dateFormatStrToTime(ConvertDateTime.FORMAT_FULL_DATETIME_EN, params.get("FirstPayment").toString());
                    if (1 < i) { //第一笔账单支付时间==第一次付款时间
                        payStartTime = ConvertDateTime.dateFormatStrToTime(ConvertDateTime.FORMAT_FULL_DATETIME_EN, params.get("SecondPayment").toString());
                    }
                    //当前账单开始时间
                    DateTime StartTimes = payStartTime.plusMonths((i <= 2 ? 0 : i - 2) * Charge);
                    //当前账单结束时间
                    DateTime EndTimes = StartTimes.plusMonths(Charge);
                    EndTimes = EndTimes.plusDays(-1);
                    //获取账单编号
                    Map<String, Object> biOutId = utilsMapper.getUUID(new HashMap<String, Object>() {{
                        put("uuid", "BiOutId");
                        put("database", Constants.DATA_SOURCE_GMIO);
                        put("surface", "tcgmio_bill_outlay");
                    }});
                    if (biOutId != null && (!biOutId.get("uuid").toString().equals(""))) {
                        int number = Integer.valueOf(biOutId.get("uuid").toString());
                        BiOutId = ComUtils.getLocalTrmSeqNum("zdzc" + (i + 1), number);
                    } else {
                        BiOutId = ComUtils.getLocalTrmSeqNum("zdzc" + (i + 1), 0);
                    }
                    //当前年份账单月租金
                    if (i != 1 && AscendingYea > 0 && AscendingVal > 0) { //0则租金不增长，不用计算
                        if (((i - 1) * Charge) % (AscendingYea * 12) == 0) { //一旦循环月份到达增长点
                            if (AscendingType == 1) {
                                price = (1 + AscendingVal * 0.01) * price;
                            } else {
                                price += AscendingVal;
                            }
                        }
                    }
                    int IfTemporary = 0;
                    if (i == 1 && Pair > 0) IfTemporary = 1;
                    BillOut.put("IfTemporary", IfTemporary);//是否是临时账单 0.否 1.是
                    int firstMon = (1 == i ? 1 : 0);
                    BillOut.put("FirstMon", firstMon);//账单是否是首月 0否 1.是
                    BillOut.put("BiOutId", BiOutId);//账单编号
                    BillOut.put("CorId", params.get("CorId"));//当前账单归属公司，涉及到支付。不同公司走不同账户
                    BillOut.put("Period", i);//账单周期
                    BillOut.put("MonthPrice", Double.valueOf(params.get("MonthPrice").toString()));//业主初始月租
                    BillOut.put("MonthPrices", price);//业主递增后月租
                    BillOut.put("BiOutName", "付业主第" + i + "次账单");//账单名称
                    BillOut.put("BiOutType", 1);//账单类型  1.业主(业主合同)   2.供应商  3.退租   4.公共事业费
                    BillOut.put("Relation", params.get("OwDeId"));//业主合同
                    BillOut.put("StartTime", ConvertDateTime.dateFormatTimeToStr(ConvertDateTime.FORMAT_ONLY_DATE_EN,StartTimes));//账单生成日
                    BillOut.put("EndTime", ConvertDateTime.dateFormatTimeToStr(ConvertDateTime.FORMAT_ONLY_DATE_EN,EndTimes));//账单结束日
                    BillOut.put("LateDay", ConvertDateTime.dateFormatTimeToStr(ConvertDateTime.FORMAT_ONLY_DATE_EN,StartTimes));//账单最晚付款时间
                    BillOut.put("StemType", 1);//支出类型   1.业主  2.供应商  3.租客
                    BillOut.put("StemId", params.get("OwId"));//业主编号
                    BillOut.put("HouId", params.get("HouId"));//房源编号
                    double BiMoney = CompuUtils.mul(price, Charge);
                    BillOut.put("BillExplain", "付业主房租:" + BiMoney);//账单说明
                    if (i == 1 && Pair > 0) { //首笔账单并且有押金
                        BiMoney += CompuUtils.mul(MonthPrice, Pair);
                        BillOut.put("BillExplain", BillOut.get("BillExplain") + ",付业主押金:" + CompuUtils.mul(MonthPrice, Pair));
                    }
                    BillOut.put("BiMoney", BiMoney);//账单金额
                    //生成账单主表
                    BillOwnerMapper.AddBillOwner(BillOut);
                }
                result = true;
            } catch (Exception e) {
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        } finally {
            lock.unlock();
        }
        return result;
    }


















    /**
     * 功能描述:
     * 根据业主账单编号获取业主账单资料
     *
     * @Author zhlu
     * @Description //TODO
     * @Date 2019/4/1 19:30
     */
    public Map<String, Object> getOwnerBillMap(Map<String, Object> params) {
        Map<String, Object> getOwnerBillMap = BillOwnerMapper.getOwnerBillMap(params);
        return getOwnerBillMap;
    }


    ///////////////////////////////////////////////////////////////////////////
    // 企业用户账单
    ///////////////////////////////////////////////////////////////////////////

    public JsonResult createTempOrder(Map<String, Object> params) {
        params.put("BiGenerated", new Date());
        String temId = comUtils.getLocalTrmSeqNumByLook("TEM", Constants.DATA_SOURCE_GMIO, "tcgmio_temporary", "TemId");
        params.put("TemId", temId);
        ParamsCommon.commonInsertParms(params, getClass());
        int i = BillOwnerMapper.insertTempOrder(params);
        if (i <= 0) {
            return JsonResult.error("临时账单创建失败");
        }
        return JsonResult.success(temId);
    }

    /**
     * 创建主账单
     *
     * @param params
     * @return
     */
    public JsonResult createOrderMain(Map<String, Object> params) {
        String id = comUtils.getLocalTrmSeqNumByLook("BIO", Constants.DATA_SOURCE_GMIO, "tcgmio_tenant_bill", "BiId");
        params.put("BiId", id);
        params.put("BiGenerated", new Date(MapUtils.getLong(params, "BiGenerated")));
        params.put("EndTime", new Date(MapUtils.getLong(params, "EndTime")));
        params.put("LateDay", new Date(MapUtils.getLong(params, "LateDay")));
        ParamsCommon.commonInsertParms(params, getClass());
        log.info("输入参数 -----> {}", params);
        int row = BillOwnerMapper.insertOrderMain(params);
        if (row <= 0) {
            return JsonResult.error("账单创建失败");
        }
        return JsonResult.success(id);
    }

    /**
     * 查询退租账单
     *
     * @param witId
     * @return
     */
    public JsonResult getBackOrder(String witId) {
        Map<String, Object> backOrder = BillOwnerMapper.getBackOrder(witId);
        return JsonResult.success(backOrder);
    }

}
